<template>
  <div class="main">
    <!-- 搜索界面 -->
    <el-card class="search" shadow="always">
      <el-form label-width="120px">
        <el-form-item label="角色名称" placeholder="角色名称">
          <el-input v-model="addRoleInfo.roleName" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="saerch">搜索</el-button>
          <el-button @click="addRoleInfo.roleName = ''">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <!-- table界面 -->
    <el-card class="search" shadow="always">
      <el-button type="primary" style="margin-bottom: 30px" @click="addRole">
        +添加角色
      </el-button>
      <!-- table -->
      <el-table :data="roleList">
        <el-table-column type="index" label="序号" width="100px" />
        <el-table-column prop="id" label="id" width="100px" />
        <el-table-column prop="roleName" label="角色名称" width="180px" />
        <el-table-column prop="createTime" label="创建时间" width="220px" />
        <el-table-column prop="updateTime" label="更新时间" width="220px" />
        <el-table-column label="操作">
          <template #default="{ row }">
            <el-button type="primary" icon="Discount" @click="authority(row)">
              分配权限
            </el-button>
            <el-button type="warning" icon="Edit" @click="editRole(row)">
              编辑
            </el-button>
            <el-button
              type="danger"
              icon="DeleteFilled"
              @click="deleteRole(row)"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <!-- 分页 -->
    <el-pagination
      v-model:current-page="roleTit.page"
      v-model:page-size="roleTit.limit"
      :page-sizes="[1, 3, 5, 11]"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
    <!-- 添加角色弹窗 -->
    <el-dialog
      v-model="adddialogVisible"
      :title="addRoleInfo.id ? '修改角色' : '添加角色'"
      width="30%"
    >
      <el-form v-model="addRoleInfo">
        <el-form-item label="添加角色">
          <el-input
            placeholder="添加角色"
            v-model="addRoleInfo.roleName"
          ></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancelAdd">取消</el-button>
          <el-button
            type="primary"
            @click="saveAddRole"
            :disabled="!addRoleInfo.roleName"
          >
            确认
          </el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 分配权限抽屉 -->
    <el-drawer v-model="authorityDrawer">
      <template #header>
        <h3>权限分配</h3>
      </template>
      <template #default>
        <el-tree
          ref="treeRef"
          :data="permissionList"
          show-checkbox
          node-key="id"
          :default-checked-keys="[7]"
          :props="defaultProps"
        />
      </template>
      <template #footer>
        <el-button type="primary" @click="savePermission">保存</el-button>
        <el-button @click="canCelPermission">取消</el-button>
      </template>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
/* 请求接口地址 */
import {
  reqGetAllRoleListAPI,
  reqAddOrUpdateRoleAPI,
  reqDeletRole,
  reqGetAllPermissAPI,
  reqSetPermisstionAPI,
} from '@/apis/permission/role'
/* TS类型 */
import type {
  resAllRole,
  roleListInfo,
  records,
  resAllPermission,
  permissionInfo,
} from '@/apis/permission/role/roleTypes'
import { ElMessage, ElTree } from 'element-plus'
import { onMounted, reactive, ref } from 'vue'
/* 用来收集初始化数据 */
const roleTit = reactive<any>({
  page: 1 /* 当前页 */,
  limit: 10 /* 每页显示信息条数 */,
  roleName: '' /* 搜索条件 为空就获取全部 有值的话及搜索对应的数据 */,
})
/* 存储所有的角色 */
const roleList = ref<roleListInfo>([])
/* 所有角色信息数据条数 */
const total = ref<number>(0)
/* 控制添加角色弹窗 */
const adddialogVisible = ref<boolean>(false)
/* 搜集添加角色信息 */
const addRoleInfo = reactive<records>({
  roleName: '',
})
/* 控制分配权限抽屉 */
const authorityDrawer = ref<boolean>(false)
/* 存储角色权限 */
const permissionList = ref<permissionInfo>([])
/* 显示树形数据 */
const defaultProps = {
  children: 'children' /* 展示树形的子节点 */,
  label: 'name' /* 树形名字 */,
}
/* 树形节点实例 */
const treeRef = ref<any>()
/* 当DOM元素渲染之后执行此操作 */
onMounted(() => getRoleList(roleTit.page, roleTit.limit, roleTit.roleName))
/* 获取初始化数据 */
const getRoleList = async (page: number, limit: number, roleName: string) => {
  const { data: res }: resAllRole = await reqGetAllRoleListAPI(
    page,
    limit,
    roleName,
  )
  /* 对返回的数据进行校验 */
  if (res.code != 200) ElMessage.error('获取失败')
  try {
    roleList.value = res.data.records
    total.value = res.data.total as number
  } catch (error) {
    alert(error)
  }
}
/* 当分页器每页显示数据条数发生变化时触发 */
const handleSizeChange = (limit: number) => {
  /* 调用接口 */
  getRoleList(roleTit.page, limit, roleTit.roleName)
}
/* 当分页器切换页数时触发 */
const handleCurrentChange = (page: number) => {
  /* 调用接口 */
  getRoleList(page, roleTit.limit, roleTit.roleName)
}
/* 添加角色回调函数 */
const addRole = () => {
  /* 显示弹窗 */
  adddialogVisible.value = true
}
/* 取消添加 */
const cancelAdd = () => {
  /* 关闭弹窗 */
  adddialogVisible.value = false
  /* 清空搜集到的数据 */
  addRoleInfo.roleName = ''
}
/* 保存添加 发起添加请求回调函数 */
const saveAddRole = async () => {
  /* 发起添加请求 */
  const { data: res }: any = await reqAddOrUpdateRoleAPI(addRoleInfo)
  /* 判断是添加还是修改 */
  if (res.code != 200) {
    ElMessage({
      type: 'error',
      message: addRoleInfo.id ? '修改失败' : '添加失败',
    })
  } else {
    ElMessage({
      type: 'success',
      message: addRoleInfo.id ? '修改成功' : '添加成功',
    })
  }
  /* 重新获取 刷新界面 */
  getRoleList(roleTit.page, roleTit.limit, roleTit.roleName)
  /* 关闭弹窗 */
  adddialogVisible.value = false
  /* 清空搜集到的数据 */
  Object.assign(addRoleInfo, {
    id: '',
    roleName: '',
    updateTime: '',
    createTime: '',
  })
}
/* 修改角色 */
const editRole = (row: records) => {
  /* 对象拷贝 */
  Object.assign(addRoleInfo, row)
  /* 显示弹窗 */
  adddialogVisible.value = true
}
/* 分配权限 */
const authority = async (row: records) => {
  authorityDrawer.value = true
  Object.assign(addRoleInfo, row)
  const { data: res }: resAllPermission = await reqGetAllPermissAPI(
    row.id as number,
  )
  if (res.code != 200) ElMessage.error('获取失败')
  permissionList.value = res.data
}
/* 保存权限 */
const savePermission = async () => {
  /* 选中节点的ID */
  let arr = treeRef.value.getCheckedKeys()
  /* 半选的ID */
  let arr1 = treeRef.value.getHalfCheckedKeys()
  /* 合并数组 */
  const newArr = arr.concat(arr1)
  /* 发起添加请求 */
  const { data: res }: any = await reqSetPermisstionAPI(
    addRoleInfo.id as number,
    newArr,
  )
  if (res.code != 200) ElMessage.error('添加权限失败')
  ElMessage.error('添加权限成功')
  /* 关闭抽屉 */
  authorityDrawer.value = false
  /* 页面刷新 */
  window.location.reload()
}
/* 取消保存权限 */
const canCelPermission = () => {
  authorityDrawer.value = false
}
/* 删除角色 */
const deleteRole = async (row: records) => {
  /* 发起删除请求 */
  const { data: res }: any = await reqDeletRole(row.id as number)
  if (res.code != 200) ElMessage.error('删除失败')
  ElMessage.success('删除成功')
  /* 重新渲染页面 */
  getRoleList(roleTit.page, roleTit.limit, roleTit.roleName)
}
/* 搜索角色 */
const saerch = () => {
  getRoleList(roleTit.page, roleTit.limit, addRoleInfo.roleName)
  /* 清除收集到的数据 */
  addRoleInfo.roleName = ''
}
</script>

<style lang="scss" scoped>
.main {
  .search {
    margin-bottom: 30px;
    .el-form {
      @include flexible(center);
      justify-content: space-between;
    }
  }
}
</style>
